package scales.xml.xpath
import scales.utils.{collection, one, toPositionalEqual, sortT, sort, comparePathsDirect}
import collection.DuplicateFilter
import scala.collection.generic.CanBuildFrom
import scales.xml.{Elem, Attributes, Attribute, XCC, XmlItem, XmlPath, ScalesXml, Text, CData}
object PositionalEquals {
implicit val xpathPositionalEqual =
toPositionalEqual[XmlItem, Elem, XCC]
}
trait XmlPathImplicits {
implicit val samePath : (XmlPath, XmlPath) => Boolean = comparePathsDirect _
implicit def fromAttrPathToAttribute(attrPath : AttributePath) : Attribute = attrPath.attribute
implicit def fromXmlPathToXPath(xmlPath : XmlPath)(
implicit cbf : CanBuildFrom[List[XmlPath], XmlPath, List[XmlPath]]) : XPath[List[XmlPath]] =
new XPath[List[XmlPath]](
XPathInfo(one(one(xmlPath)), initialNode = true, eager = true), cbf)
implicit def fromXPathToIterable(xpath : XPath[_]) : Iterable[XmlPath] = {
val nodes = xpath.path.nodes.flatten
if (nodes.size < 2) nodes
else
DuplicateFilter(sort[XmlItem, Elem, XCC](paths = nodes)(ScalesXml.xpathSortingClassManifest))(PositionalEquals.xpathPositionalEqual)
}
implicit def fromAttributePathsToIterable[T <: Iterable[XmlPath]](attrs : AttributePaths[T]) : Iterable[AttributePath] =
if (attrs.attributes.size < 2) attrs.attributes
else
sortT[XmlItem, Elem, XCC, AttributePath](attrs.attributes.map { x => (x, x.parent) }).map { x => x._1 }
implicit def fromPathToComparisoms(path : XmlPath) = XmlPathComparisoms(path)
implicit def fromAPathToAComparisoms(path : AttributePath) = AttributePathComparisoms(path)
implicit val XPathToBoolean = (x : XPath[_]) => !x.path.nodes.isEmpty
implicit val AttributePathsToBoolean = (x : AttributePaths[_]) => !x.attributes.isEmpty
implicit val IterableToBoolean = (x : Iterable[_]) => !x.isEmpty
implicit val StringToBoolean = (x : String) => x.length > 0
implicit val NumberToBoolean = (x : Number) => x.longValue() > 0
implicit val BooleanToBoolean = (x : Boolean) => x
}
trait XmlPaths {
def raw[T <: Iterable[XmlPath]](xpath : XPath[T]) : Iterable[XmlPath] =
xpath.path.nodes.flatten
def lazyRaw[T <: Iterable[XmlPath]](xpath : XPath[T]) : Iterable[XmlPath] =
xpath.path.nodes.iterator.toIterable.flatten
def viewed(xmlPath : XmlPath)(
implicit cbf : CanBuildFrom[List[XmlPath], XmlPath, List[XmlPath]]) : XPath[List[XmlPath]] =
new XPath[List[XmlPath]](
XPathInfo(one(one(xmlPath).view).view, initialNode = true), cbf)
import ScalesXml._
def eager(xmlPath : XmlPath)(
implicit cbf : CanBuildFrom[List[XmlPath], XmlPath, List[XmlPath]]) : XPath[List[XmlPath]] =
fromXmlPathToXPath(xmlPath)
val isText = (x : XmlPath) => x.isItem == true && (x.item().isInstanceOf[Text] || x.item().isInstanceOf[CData])
def attributes(implicit path : XmlPath) : Attributes = path.tree.section.attributes
def elem(implicit path : XmlPath) : Elem = path.tree.section
val isItem = (x : XmlPath) => x.isItem
val isElem = (x : XmlPath) => !x.isItem
}